///////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007 - 2008 XamlGuide.NET. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////

if (!window.SilverCalendar)
	window.SilverCalendar = {};

SilverCalendar.Page = function() 
{
}

SilverCalendar.Page.prototype =
{
	handleLoad: function(control, userContext, rootElement) 
	{
		this.control = control;
		
		// Sample event hookup:	
		rootElement.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.handleMouseDown));
	},
	
	// Sample event handler
	handleMouseDown: function(sender, eventArgs) 
	{
		// The following line of code shows how to find an element by name and call a method on it.
		// this.control.content.findName("Timeline1").Begin();
	}
}
var currentYear = 2007;
var selectedMonth = 0;
// Available values: "image" or "video".
var mediaType = "image";
// Media (image/video) list.
var arrMediaList = null;

// Core file list for SilverCalendar.
function CoreFilesList()
{
    this.mediaResourceFile = "CalendarMediaResource.xml";
    this.templateListFile = "CalendarTemplates.xml";
}
var myCoreFilesList = new CoreFilesList();
var mediaListImage;
var mediaListVideo;
var templateList;
var selectedTemplateIndex;

// Current version of this application, it will be used for downloading files with the latest version.
var applicationVersion = "2.0.0";

var selectedTemplateIndex = 0;
var selectedMediaType = "Image";
var selectedMediaList;

// Text content for each month.
var arrMonthList = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
// Text content for each week day.
var arrWeekList = new Array("S","M","T","W","T","F","S");
// Colors for the background selection list(example, "#FF00FFFF", "Aqua").
var arrBackgroundList = new Array("#FF2CB5F4", "#FF32CD32","#FFADFF2F","Orange","#FF1493","Aqua","#FFFFD700","Silver");

function onLoaded(sender, args)
{
    loadBackgroundList(sender, args);
    loadCoreFiles(sender, args);
}

// Load the core files for this application.
function loadCoreFiles(sender, args)
{
    var coreZipFileName = "SilverCalendarCoreFile.zip?v=" + applicationVersion;
    downloadFile(coreZipFileName, startCalendar, sender, args);
}

function startCalendar(sender, args)
{
    // Parse templates list from xml.
    var templatesXml = sender.GetResponseText(myCoreFilesList.templateListFile);
    var templatesXmlParsed = parseXmlContent(templatesXml);
    templateList = templatesXmlParsed.getElementsByTagName("Template");
    if(templateList.length == 0)
    {
        alert("No templates found.");
        return;
    }
    
    // Show template thumb in template list.
    selectedTemplateIndex = 0;
    moveToTemplate(selectedTemplateIndex, sender, args);    
    
    // Parse media resource list from xml.
    var mediaResourceXml = sender.GetResponseText(myCoreFilesList.mediaResourceFile);
    var mediaResourceXmlParsed = parseXmlContent(mediaResourceXml);
    mediaListImage = mediaResourceXmlParsed.getElementsByTagName("ImageMedia");
    mediaListVideo = mediaResourceXmlParsed.getElementsByTagName("VideoMedia");
    
    // Set media type.
     var mediaTypeListContainer = sender.findName("MediaTypeListContainer");
    if(mediaTypeListContainer.children.count > 0)
    {
        for(var i = 0; i < mediaTypeListContainer.children.count; i ++)
        {
           mediaTypeListContainer.children.getItem(i).foreground = "#FFFFFFFF";
           if(mediaType == mediaTypeListContainer.children.getItem(i).text.toLowerCase())
            {
                mediaTypeListContainer.children.getItem(i).foreground = "#FFCC0000";
                break;
            }
        }
    }
    
    // http://www.w3schools.com/jsref/jsref_obj_date.asp
    // http://www.irt.org/script/date.htm
    var today = new Date();
    selectedMonth = today.getMonth();
    currentYear = today.getFullYear();
    // Download the selected template xaml content.
    var xamlTemplateFilePath = templateList[selectedTemplateIndex].attributes.getNamedItem("XamlPath").value;
    downloadXamlFile(xamlTemplateFilePath, sender, args);
}

// Move to specific template and apply the calendar with the template.
function moveToTemplate(templateIndex, sender, args)
{
    var plugin = sender.getHost();
    
    // Show the template thumb in the template list container.
    var templateListContainer = plugin.content.findName("TemplateListContainer");
    templateListContainer.children.clear();
    var thumbUrl = templateList[templateIndex].attributes.getNamedItem("ThumbUrl").value;
    var templateItemXaml = '<Image Width="180" Height="180" Source="' + thumbUrl + '"/>';
    templateListContainer.children.add(plugin.content.createFromXaml(templateItemXaml));
    var TemplateThumbIn = plugin.content.findName("TemplateThumbIn");
    TemplateThumbIn.begin();
    var selectedTemplateTitle = plugin.content.findName("SelectedTemplateTitle");
    selectedTemplateTitle.text = templateList[templateIndex].attributes.getNamedItem("DisplayName").value;
    
    var TemplatesPageSum = plugin.content.findName("TemplatesPageSum");
    TemplatesPageSum.Text = (templateIndex + 1) + " / " + templateList.length;
    
    var xamlTemplateFilePath = templateList[selectedTemplateIndex].attributes.getNamedItem("XamlPath").value;
    downloadXamlFile(xamlTemplateFilePath, sender, args);
}

function moveToNextTemplate(sender, args)
{
    var templateCount = templateList.length;
    if(templateCount > 0)
    {
        if(selectedTemplateIndex == templateCount - 1)
            selectedTemplateIndex = 0;
        else
            selectedTemplateIndex ++;
        moveToTemplate(selectedTemplateIndex, sender, args);
    }
}

function moveToPrevTemplate(sender, args)
{
    var templateCount = templateList.length;
    if(templateCount > 0)
    {
        if(selectedTemplateIndex == 0)
            selectedTemplateIndex = templateCount - 1;
        else
            selectedTemplateIndex --;
        moveToTemplate(selectedTemplateIndex, sender, args);
    }
}

// Parse XML content.
function parseXmlContent(xmlContent)
{    
    // create appropiate XML document
    if (window.ActiveXObject) {
        // IE 6 (and 7)
        doc = new ActiveXObject("Microsoft.XMLDOM");
        if (!doc.loadXML(xmlContent)){
            // handle parse error
            throw doc.parseError.reason;
        }
    }
    else {
        // Firefox and others
        var parser = new DOMParser();
        doc = parser.parseFromString(xmlContent, "text/xml");
    }
    return doc;
}

function loadPageBar(sender, args)
{
    var calendarMediaContainer = sender.findName("CalendarMediaContainer");
    var AdjustCalendarLoc = sender.getHost().content.findName("AdjustCalendarLoc");
    var AdjustCalendarLocLeft = sender.getHost().content.findName("AdjustCalendarLocLeft");
    var newLeft = (770 - calendarMediaContainer.width)/2;
    AdjustCalendarLocLeft.To = newLeft;
    AdjustCalendarLoc.Begin();
    
    var pageBarContainer = sender.findName("CalendarPageBarContainer");
    var itemWidth = 25;
    var count = parseInt(calendarMediaContainer.width / itemWidth);
    var pageBarXaml = '';
    pageBarContainer.children.clear();
    for(var i = 0; i < count; i ++)
    {
        pageBarXaml = '<Canvas Canvas.Top="0" Canvas.Left="' + itemWidth*i + '" Width="' + itemWidth + '" Height="29">';
		pageBarXaml += ' 	<Rectangle Canvas.Left="12" Canvas.Top="17" Width="10" Height="10" Fill="Black"></Rectangle>';
		pageBarXaml += ' 	<Rectangle Canvas.Left="15" Canvas.Top="0" Width="4" Height="22" Fill="White"></Rectangle>';
		pageBarXaml += '</Canvas>';
		pageBarContainer.children.add(sender.getHost().content.createFromXaml(pageBarXaml));
    }
}

// Change the background color.
function changeBackground(selectedColor, sender)
{
    var mainBgStoryboard = sender.findName("MainBgStoryboard");
    var mainBgColorAnimation = sender.findName("MainBgColorAnimation");
    mainBgColorAnimation.to = selectedColor;
    mainBgStoryboard.begin();
}
// Load background color list.
function loadBackgroundList(sender, args)
{
    var backgroundSelectContainer = sender.findName("BackgroundSelectContainer");
    var plugin = sender.getHost();
    var xamlContent = "";
    // The width and height for a background select box.
    var backgroundSelectBoxWidth = 20;
    for(var i = 0; i < arrBackgroundList.length; i ++)
    {
        var tempLeft = (backgroundSelectBoxWidth + 2) * i;
        xamlContent = '<Rectangle xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="rectColorBox' + i + '" Cursor="Hand" Width="' + backgroundSelectBoxWidth + '" Height="' + backgroundSelectBoxWidth + '" Canvas.Left="' + tempLeft + '" Canvas.Top="0" Stroke="White" StrokeThickness="1" Fill="' + arrBackgroundList[i] + '" MouseLeftButtonUp="selectBackgroundClick" MouseEnter="selectBackgroundMouseOver" MouseLeave="selectBackgroundMouseLeave">';
        xamlContent += '<Rectangle.RenderTransform><TransformGroup><ScaleTransform ScaleX="1" ScaleY="1" CenterX="' + backgroundSelectBoxWidth/2 + '" CenterY="' + backgroundSelectBoxWidth/2 + '"/></TransformGroup></Rectangle.RenderTransform>';
        xamlContent += '</Rectangle>';
        backgroundSelectContainer.children.add(plugin.content.createFromXaml(xamlContent));
    }
    // Set the default background color using the first color.
    changeBackground(arrBackgroundList[0], sender);
}

function initMediaObject(sender, args)
{
    var plugin = sender.getHost();
    var calendarMediaContainer = sender.findName("CalendarMediaContainer");
    var xamlFragment = '';
    if(mediaType == "video")
    {
        selectedMediaList = mediaListVideo;
        xamlFragment = '<MediaElement xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="mediaObject" Stretch="Fill" Source="" Width="' + calendarMediaContainer.width + '" Height="' + calendarMediaContainer.height + '"/>';
    }
    else
    {
        selectedMediaList = mediaListImage;
        xamlFragment = '<Image xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="mediaObject" Stretch="Fill" Source="" Width="' + calendarMediaContainer.width + '" Height="' + calendarMediaContainer.height + '"></Image>';
    }
    if(calendarMediaContainer.children.count>=1)
        calendarMediaContainer.children.clear();
    calendarMediaContainer.children.add(plugin.content.createFromXaml(xamlFragment));
}

function loadCalendar(sender,args)
{
    // Get the days count in the selected month.
    var daysInSelectedMonth = 32 - new Date(currentYear, selectedMonth, 32).getDate();
    var firstDayInWeek = new Date(currentYear, selectedMonth, 1).getDay();
    
    var plugin = sender.getHost();
    
    // Show the media content.
    if(mediaType == "video")
    {
        var mediaObject = sender.findName("mediaObject");
        mediaObject.source = selectedMediaList[selectedMonth].attributes.getNamedItem("Url").value;
    }
    else
    {
        downloadImage(selectedMediaList[selectedMonth].attributes.getNamedItem("Url").value, sender, args);
    }
    
    // Show calendar month content.
    var calendarMonth = sender.findName("CalendarMonth");
    calendarMonth.text = arrMonthList[selectedMonth] + " " + currentYear;
    
    // Show calendar days content.
    var calendarDaysContainer = sender.findName("CalendarDaysContainer");
    // Remove exist days list for the previous month.
    if(calendarDaysContainer.children.count>0)
    {
        calendarDaysContainer.children.clear();
    }
    var dayTextHeight = 18;
    var dayTextWidth = 22;
    var tmpDayInWeek = firstDayInWeek;
    var virtualDaysInSelectedMonth = daysInSelectedMonth;
    var showDaysInOneRow = true;
    var paddingTopWeek = 5;
    // If one row can't display 31 days, will display one week each row.
    var calendarDaysContainer = sender.findName("CalendarDaysContainer");
    if(calendarDaysContainer.width < 685)
    {
        virtualDaysInSelectedMonth += tmpDayInWeek;
        showDaysInOneRow = false;
        tmpDayInWeek = 0;
    }
    // Show week days description.
    for(var i = 1; i <= virtualDaysInSelectedMonth; i ++)
    {
        if(showDaysInOneRow == false && i > 7)
        {
            break;
        }
        var textColor = '';
        if(tmpDayInWeek == 0 || tmpDayInWeek == 6)
        {
            textColor = ' Foreground="Red"';
        }
        var paddingLeft = (i - 1) * dayTextWidth;        
        // Add week days description.
        if(showDaysInOneRow == true || (showDaysInOneRow == false && i <=7))
        {
            var dayXaml = '<TextBlock FontFamily="Arial" FontSize="12" Canvas.Left="' + paddingLeft + '" Canvas.Top="' + paddingTopWeek + '"'+textColor+'>'+ arrWeekList[tmpDayInWeek] + '</TextBlock>';
            calendarDaysContainer.children.add(plugin.content.createFromXaml(dayXaml));
        }
        if(tmpDayInWeek >=6)
            tmpDayInWeek = 0;
        else
            tmpDayInWeek ++;
    }
    // Show days in this month.
    var dayTextRowIndex = 0;
    var currentDayText = 0;
    if(showDaysInOneRow == false)
        tmpDayInWeek = 0;
    else
        tmpDayInWeek = firstDayInWeek;
    for(var i = 1; i <= virtualDaysInSelectedMonth; i ++)
    {
        var paddingLeft = (i - 1) * dayTextWidth;
        if(showDaysInOneRow == false)
        {
            if(i == 7 * dayTextRowIndex + 1)
                dayTextRowIndex ++;
            paddingLeft = (i - 1 - 7 * (dayTextRowIndex-1)) * dayTextWidth;
        }
        else
        {
            dayTextRowIndex = 1;
        }
        var actualDayText = i;
        if(showDaysInOneRow == false)
        {
            actualDayText = i - firstDayInWeek;
            if(actualDayText <= 0)
                actualDayText = '';
        }
        var textColor = '';
        if(tmpDayInWeek == 0 || tmpDayInWeek == 6)
            textColor = ' Foreground="Red"';
        var paddingTop = dayTextHeight * dayTextRowIndex + paddingTopWeek;
        var dayXaml = '';
        dayXaml = '<TextBlock FontFamily="Arial" FontSize="12" FontWeight="Bold" FontStyle="Italic" Canvas.Left="' + paddingLeft + '" Canvas.Top="' + paddingTop + '"'+textColor+'>'+ actualDayText + '</TextBlock>';
        calendarDaysContainer.children.add(plugin.content.createFromXaml(dayXaml));
        
        if(tmpDayInWeek >=6)
            tmpDayInWeek = 0;
        else
            tmpDayInWeek ++;
    }
}

function NavButtonMouseEnter(sender, args)
{
    var plugin = sender.getHost();
    var xaml = '<SolidColorBrush Color="#FF676767" Opacity="0.4"/>';
    sender.fill = plugin.content.createFromXaml(xaml);
}
function NavButtonMouseLeave(sender, args)
{
    var plugin = sender.getHost();
    var xaml = '<SolidColorBrush Color="White" Opacity="0.4"/>';
    sender.fill = plugin.content.createFromXaml(xaml);
}
function PrevNavButtonClick(sender, args)
{
    if(selectedMonth == 0)
    {
        selectedMonth = 11;
        currentYear --;
    }
    else
        selectedMonth --;
    
    loadCalendar(sender);
}
function NextNavButtonClick(sender, args)
{
    if(selectedMonth == 11)
    {
        selectedMonth = 0;
        currentYear ++;
    }
    else
        selectedMonth ++;
    loadCalendar(sender);
}
/***************** Events for download images - begin *****************/
function downloadImage(imageFilePath, sender, args)
{
    var mediaObject = sender.findName("mediaObject");
    mediaObject.source = "";
    var plugin = sender.getHost();
    var downloader = plugin.createObject("downloader");
    downloader.addEventListener("downloadProgressChanged", onDownloadProgressChanged);
    downloader.addEventListener("completed", onDownloadCompleted);
    downloader.addEventListener("DownloadFailed", onDownloadFailed);
    downloader.open("GET", imageFilePath);
    downloader.send();
}

function onDownloadProgressChanged(sender, args)
{
    var percentage = Math.floor(sender.downloadProgress * 100);
    var downloadProgress = sender.FindName("DownloadProgress");
    downloadProgress.text = "Downloading image: " + percentage + "%";
}
function onDownloadCompleted(sender, args)
{
    var mediaObject = sender.findName("mediaObject");
    mediaObject.setSource(sender, "");
    var downloadProgress = sender.FindName("DownloadProgress");
    downloadProgress.text = "";
}
function onDownloadFailed(sender, args)
{
    alert("Failed to download the image.");
}
/***************** Events for download xaml files - begin *****************/
function downloadXamlFile(xamlFilePath, sender, args)
{
    var plugin = sender.getHost();
    var downloader = plugin.createObject("downloader");
    downloader.addEventListener("downloadProgressChanged", onDownloadXamlProgressChanged);
    downloader.addEventListener("completed", onDownloadXamlCompleted);
    downloader.addEventListener("DownloadFailed", onDownloadXamlFailed);
    downloader.open("GET", xamlFilePath);
    downloader.send();
}
function onDownloadXamlProgressChanged(sender, args)
{
    var percentage = Math.floor(sender.downloadProgress * 100);
    var downloadProgress = sender.findName("DownloadProgress");
    downloadProgress.text = "Downloading XAML: " + percentage + "%";
}
function onDownloadXamlCompleted(sender, args)
{
    //var downloadProgress = sender.FindName("DownloadProgress");
    //downloadProgress.text = "";
    var plugin = sender.getHost();
    var xamlContent = plugin.content.createFromXamlDownloader(sender, "");
    var calendarTemplateContainer = sender.findName("CalendarTemplateContainer");
    calendarTemplateContainer.children.clear();
    calendarTemplateContainer.children.add(xamlContent);
    calendarTemplateContainer["Canvas.Left"] = 0;
    initMediaObject(calendarTemplateContainer, args);
    loadCalendar(calendarTemplateContainer, args);    
    loadPageBar(calendarTemplateContainer, args);
}
function onDownloadXamlFailed(sender, args)
{
    alert("Failed to download the xaml file.");
}
/***************** Events for file download - begin *****************/
function downloadFile(filePath, completedFunction, sender, args)
{
    var plugin = sender.getHost();
    var downloader = plugin.createObject("downloader");
    downloader.addEventListener("downloadProgressChanged", onDownloadFileProgressChanged);
    if(completedFunction != null)
    {
        downloader.addEventListener("completed", completedFunction);
    }
    downloader.addEventListener("DownloadFailed", onDownloadFileFailed);
    downloader.open("GET", filePath);
    downloader.send();
}
function onDownloadFileProgressChanged(sender, args)
{
    var percentage = Math.floor(sender.downloadProgress * 100);
    var downloadProgress = sender.findName("DownloadProgress");
    downloadProgress.text = "Loading " + sender.Uri + ": " + percentage + "%";
}
function onDownloadFileFailed(sender, args)
{
    alert("Failed to download the file: " + sender.Uri);
}

// Show/hide calendar nav bar when mouseenter/mouseleave.
function CalendarMouseEnter(sender, args)
{
    var MonthNavContainer = sender.FindName("MonthNavContainer");
    MonthNavContainer.opacity = 1;
}
function CalendarMouseLeave(sender, args)
{
    var MonthNavContainer = sender.FindName("MonthNavContainer");
    MonthNavContainer.opacity = 0;
}
// Hyperlink events.
function HyperlinkHover(sender, args)
{
    sender.Foreground = '#FF2CB5F4';
}
function HyperlinkMouseLeave(sender, args)
{
    sender.Foreground = 'White';
}
function HyperlinkClick(sender, args)
{
    if(sender.Name == "LinkXamlGuideHomepage")
    {
        window.location.href = "http://www.xamlguide.net";
    }
    if(sender.Name == "LinkSilverCalendar")
    {
        window.location.href = "http://www.xamlguide.net/silvercalendar";
    }
}
// Click the color to change the background.
function selectBackgroundClick(sender, args)
{
    var selectedColor = getFillColor(sender.fill.color);
    changeBackground(selectedColor, sender);
}

function selectBackgroundMouseOver(sender, args)
{
    var colorBoxAnimation1 = sender.findName("ColorBoxAnimation1");
    colorBoxAnimation1.stop();
    colorBoxAnimation1["Storyboard.TargetName"] = sender.name;
    colorBoxAnimation1.begin();
}

function selectBackgroundMouseLeave(sender, args)
{
    var colorBoxAnimation2 = sender.findName("ColorBoxAnimation2");
    colorBoxAnimation2.stop();
    colorBoxAnimation2["Storyboard.TargetName"] = sender.name;
    colorBoxAnimation2.begin();
}

function getFillColor(color) {
   var fill = color;
   if (fill < 0) {
      fill = (16777216 + parseInt(fill));
   }
   fill = fill.toString(16);
   if (fill.length > 6) {
      fill = fill.substr(fill.length - 6);
   }
   while (fill.length < 6) {
      fill = "0" + fill;
   }
   fill = "#ff" + fill;
   return fill;
} 
// Change media type events.
function changeMediaTypeMouseOver(sender, args)
{
    sender.foreground = "#FFCC0000";
}

function changeMediaTypeMouseOut(sender, args)
{
    if(mediaType != sender.text.toLowerCase())
    {
        sender.foreground = "#FFFFFFFF";
    }
}

function changeMediaTypeMouseClick(sender, args)
{
    var mediaTypeListContainer = sender.findName("MediaTypeListContainer");
    if(mediaTypeListContainer.children.count > 0)
    {
        for(var i = 0; i < mediaTypeListContainer.children.count; i ++)
        {
           mediaTypeListContainer.children.getItem(i).foreground = "#FFFFFFFF";
        }
    }
    sender.foreground = "#FFCC0000";
    mediaType = sender.text.toLowerCase();
    var calendarTemplateContainer = sender.findName("CalendarTemplateContainer");
    initMediaObject(calendarTemplateContainer, args);
    loadCalendar(calendarTemplateContainer, args);    
    loadPageBar(calendarTemplateContainer, args);
}